
import re
import os
import os.path
import sys

import xp3
import nsa
from archive import *

def save_as_temp_file(content, name):
	#TODO: use a better approach...
	import tempfile
	import os
	fd, path = tempfile.mkstemp(suffix = '-'+name, prefix = 'fate-resource-')
	fp = os.fdopen(fd, 'wb')
	fp.write(content)
	fp.close()
	return path

def tlg_to_png(path):
	tlg_path = path
	png_path = path + '.png'
	try:
		import tlg
		tlg.tlg_file_to_png_file(tlg_path, png_path)
	except Exception, e:
		return tlg_path
	else:
		return png_path

def call_on_temp_stream(content, name, callback, convert_tlg_to_bmp=True):
	if convert_tlg_to_bmp and re.search(r'\.tlg$', name, re.I):
		import tlg
		bmp = tlg.tlg_string_to_bmp_string(content)
		from cStringIO import StringIO
		return callback(StringIO(bmp))
	else:
		from cStringIO import StringIO
		return callback(StringIO(content))

def basename(path):
	x = path.rfind('/')
	y = path.rfind('\\')
	if x < y:
		return path[y+1:]
	else:
		return path[x+1:]

class Resource:
	def __init__(self, root='.', delay=True):
		files = [os.path.join(root, f) for f in os.listdir(root) if re.match(r'.*\.(nsa|xp3)$', f, re.I)]
		files.sort()

		self.info = [(f, os.path.getmtime(f)) for f in files]
		self.files = files
		self.resources = {}

		self.root = root

		if not delay:
			self.load_all()

	def load_all(self):
		if not self.files:
			return
		self.files.reverse()
		for f in self.files:
			for entry in Entries(f):
				name = basename(entry.name)
				if name not in self.resources:
					self.resources[name] = entry
		self.files = []

	def get_resource(self, path):
		path = basename(path)
		if path in self.resources:
			return self.resources[path]
		while self.files:
			result = None
			f = self.files.pop()
			for entry in Entries(f):
				name = basename(entry.name)
				if name not in self.resources:
					self.resources[name] = entry
					if name == path:
						result = entry
			if result:
				return result

	def get_resource_as_file(self, path, convert_tlg_to_png=True):
		entry = self.get_resource(path)
		if not entry:
			return
		# TODO:
		# 1. extract files to a temp folder, instead of lonely files
		# 2. don't redecode
		path = re.sub(r'[/\\()]', '-', entry.name)
		path = xp3.force_encode_path(path)
		#path = xp3.encode_path(path)
		if isinstance(path, unicode):
			path = path.encode(sys.getfilesystemencoding())
		path = save_as_temp_file(entry.decode(), path)
		if convert_tlg_to_png and re.search(r'\.tlg$', path, re.I):
			path = tlg_to_png(path)
		return path

	def call_resource_as_stream(self, path, callback, convert_tlg_to_bmp=True):
		entry = self.get_resource(path)
		if not entry:
			return
		path = re.sub(r'[/\\()]', '-', entry.name)
		path = xp3.force_encode_path(path)
		#path = xp3.encode_path(path)
		if isinstance(path, unicode):
			path = path.encode(sys.getfilesystemencoding())
		return call_on_temp_stream(entry.decode(), path, callback, convert_tlg_to_bmp=True)

	def __getitem__(self, path):
		return self.get_resource(path)


if __name__ == '__main__':
	from time import time

	start = time()
	r = Resource(delay=False) # 1.03s -> 0.64
	print time() - start

